package com.ziven.common.widget.index;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.ziven.common.widget.R;
import com.ziven.easygo.util.BiCarry;
import com.ziven.easygo.util.ViewUtils;

/**
 * @author Ziven
 */
public class ContainerLayout extends LinearLayout implements IndexCallback {

    private static final int SCROLL = 0;
    private static final int TOP = 1;
    private static final int MIDDLE = 2;
    private static final int BOTTOM = 3;
    private final int bubbleViewShowStyle;
    private final int bubbleViewShowPadding;
    private int containerHeight;
    private int bubbleHeight;
    private BubbleLayout bubbleLayout;
    private BiCarry<Boolean, BubbleLayout> viewBiCarry;

    public ContainerLayout(@NonNull Context context) {
        this(context, null);
    }

    public ContainerLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ContainerLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public ContainerLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ContainerLayout, defStyleAttr, defStyleRes);
        bubbleViewShowStyle = typedArray.getInt(R.styleable.ContainerLayout_bubble_view_fixed, SCROLL);
        bubbleViewShowPadding = typedArray.getDimensionPixelSize(R.styleable.ContainerLayout_bubble_view_fixed_padding, 0);
        typedArray.recycle();
        setOrientation(HORIZONTAL);
    }

    public void setViewBiCarry(@NonNull BiCarry<Boolean, BubbleLayout> carry) {
        viewBiCarry = carry;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        ViewUtils.forEachChild(this, child -> {
            if(child instanceof IndexInterface) {
                ((IndexInterface) child).setIndexCallback(this);
            } else if(child instanceof BubbleLayout) {
                bubbleLayout = (BubbleLayout) child;
                bubbleLayout.setVisibility(INVISIBLE);
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        containerHeight = getMeasuredHeight();
    }

    @Override
    public void startUpdateIndexName(int top, int bottom) {
        if(bubbleLayout == null) {
            return;
        }
        bubbleLayout.setVisibility(VISIBLE);
        bubbleHeight = bubbleLayout.getBubbleHeight();
        int bubbleShowY;
        switch (bubbleViewShowStyle) {
            case TOP:
                bubbleShowY = top + bubbleViewShowPadding;
                if(bubbleShowY + bubbleHeight > containerHeight) {
                    bubbleShowY = 0;
                }
                break;
            case MIDDLE:
                bubbleShowY = Math.max(0, (bottom - top - bubbleHeight) / 2 + top);
                break;
            case BOTTOM:
                int paddingBottom = bubbleViewShowPadding + bubbleHeight;
                bubbleShowY = bottom >= paddingBottom
                        ? bottom - paddingBottom
                        : containerHeight >= bubbleHeight
                        ? containerHeight - bubbleHeight
                        : containerHeight;
                break;
            default:
                bubbleShowY = 0;
                break;
        }
        bubbleLayout.setTranslationY(bubbleShowY);
        getViewBiCarry().carry(true, bubbleLayout);
    }

    @Override
    public void updateIndexName(int index, @NonNull String name, int x, int y) {
        if(bubbleLayout == null) {
            return;
        }
        bubbleLayout.setText(name);
        if(bubbleViewShowStyle == SCROLL) {
            int drawY = Math.min(containerHeight - bubbleHeight, Math.max(0, y - bubbleHeight / 2));
            bubbleLayout.setTranslationY(drawY);
        }
    }

    @Override
    public void endUpdateIndexName() {
        if(bubbleLayout == null) {
            return;
        }
        getViewBiCarry().carry(false, bubbleLayout);
    }

    @NonNull
    private BiCarry<Boolean, BubbleLayout> getViewBiCarry() {
        if(viewBiCarry != null) {
            return viewBiCarry;
        }
        viewBiCarry = (isShow, view) -> {
            if(isShow) {
                startShowAnim(view);
            } else {
                startHideAnim(view);
            }
        };
        return viewBiCarry;
    }

    private void startShowAnim(@NonNull BubbleLayout view) {
        view.setScaleX(0.5f);
        view.setScaleY(0.5f);
        view.setAlpha(0.0f);
        view.animate().scaleX(1.0f).scaleY(1.0f)
                .alpha(1.0f).setDuration(120).start();
    }

    private void startHideAnim(@NonNull BubbleLayout view) {
        view.setScaleX(1.0f);
        view.setScaleY(1.0f);
        view.setAlpha(1.0f);
        view.animate().scaleX(0.5f).scaleY(0.5f).alpha(0.0f)
                .setDuration(120).setStartDelay(120)
                .withEndAction(() -> view.setVisibility(GONE))
                .start();
    }
}
